package exploits

import (
	"io"
	"net"
	"prismx_cli/core/models"
	"prismx_cli/utils/netUtils"
	"strconv"
	"strings"
	"time"
)

// init 注册插件插件
func init() {

	models.Register(models.AppVulInfo{
		App:   "ActiveMQ",
		Query: "protocol:\"apachemq\"",
		Meta: models.VulMeta{
			Name:        "[疑似存在]Apache_Activemq_RCE CVE-2023-46604",
			Tags:        []string{"remote_code_execution"},
			Author:      "一曲成殇",
			Description: "攻击者可构造恶意请求通过Apache ActiveMQ的61616端口发送恶意数据导致远程代码执行，从而完全控制Apache ActiveMQ服务器。",
			Homepage:    "https://activemq.apache.org/",
			Level:       5,
			References:  "https://github.com/Hutt0n0/ActiveMqRCE/tree/master",
			Solution:    "根据影响版本中的信息，排查并升级到安全版本，或直接访问参考链接获取官方更新指南。",
			CreateAt:    "2023-12-04",
			Available:   false,
			Steps: models.StepsMeta{
				VerifySteps: models.VerifySteps{
					VerifyGo: func(scheme, ip string, port int, duration time.Duration) (result models.VulResult) {

						parseIntPart := func(part string) int {
							if i, err := strconv.Atoi(part); err == nil {
								return i
							}
							return 0
						}
						isVersionInRange := func(version1, version2 string) bool {
							v1 := strings.Split(version1, ".")
							v2 := strings.Split(version2, ".")

							max := len(v2)
							if len(v1) > len(v2) {
								max = len(v1)
							}

							for i := 0; i < max; i++ {
								part1 := 0
								if i < len(v1) {
									part1 = parseIntPart(v1[i])
								}

								part2 := parseIntPart(v2[i])

								if part1 > part2 {
									return false
								} else if part1 < part2 {
									return true
								}
							}
							return false
						}

						conn, err := netUtils.SendDialTimeout("tcp", net.JoinHostPort(ip, strconv.Itoa(port)), duration)
						if err != nil {
							result.Response = err.Error()
							return
						}

						defer conn.Close()

						all, err := io.ReadAll(conn)
						if err != nil {
							return
						}
						body := string(all)
						lastSpace := strings.LastIndex(body, " ")
						if lastSpace == -1 {
							return
						}
						// 如果找到了最后一个空格
						textAfterLastSpace := body[lastSpace+1:]
						textAfterLastSpace = strings.ReplaceAll(textAfterLastSpace, " ", "")

						if isVersionInRange(textAfterLastSpace, "5.18.3") {
							result.State = true
							result.Response = body
							result.Request = "<NULL>"
						}
						return
					},
				},
			},
		},
	})
}
